<!-- 文件上传 -->
<script setup lang="ts">
import type { ExtendedFilesCardProps } from '@/stores/modules/files';
import { useFileDialog } from '@vueuse/core';
import { ElMessage } from 'element-plus';
import { uploadFile } from '@/api/system';
import { useFilesStore } from '@/stores/modules/files';
import { useModelStore } from '@/stores/modules/model';

type FilesList = ExtendedFilesCardProps;

const filesStore = useFilesStore();
const modelStore = useModelStore();

// 允许的文件类型
const allowedFileTypes = [
  '.doc',
  '.docx',
  '.wps',
  '.ppt',
  '.pptx',
  '.xls',
  '.xlsx',
  '.md',
  '.txt',
  '.pdf',
];

// 图片文件选择器 (最多3张图片)
const {
  open: openImage,
  reset: resetImage,
  onChange: onImageChange,
} = useFileDialog({
  accept: 'image/*',
  multiple: true,
});

// 其他文件选择器 (只能上传一份文件)
const {
  open: openFiles,
  reset: resetFiles,
  onChange: onFilesChange,
} = useFileDialog({
  // 限制只能选择指定类型的文件
  accept: allowedFileTypes.join(','),
  multiple: false, // 只允许选择一个文件
});

onImageChange((files) => {
  if (!files)
    return;

  // 计算当前已有的图片数量
  const currentImageCount = filesStore.filesList.filter(file => file.file.type.startsWith('image/')).length;

  // 检查添加新图片后是否会超过限制
  if (currentImageCount + files.length > 3) {
    ElMessage.warning(`最多只能上传3张图片，当前还能上传${3 - currentImageCount}张`);
    return;
  }

  processFiles(files);
  nextTick(() => resetImage());
});

onFilesChange((files) => {
  if (!files)
    return;

  // 检查文件类型是否符合要求
  const selectedFile = files[0];
  const fileExtension = `.${selectedFile.name.split('.').pop()?.toLowerCase()}`;

  if (!allowedFileTypes.includes(fileExtension)) {
    ElMessage.warning(`只能上传以下格式的文件: ${allowedFileTypes.join(', ')}`);
    return;
  }

  // 检查是否已经有一个文件了
  const currentFileCount = filesStore.filesList.length;
  if (currentFileCount > 0) {
    // 检查是否已经有非图片文件
    const hasNonImageFile = filesStore.filesList.some(file => !file.file.type.startsWith('image/'));
    if (hasNonImageFile) {
      ElMessage.warning('只能上传一份文件');
      return;
    }
  }

  processFiles(files);
  nextTick(() => resetFiles());
});

async function processFiles(files: FileList) {
  const arr = [] as FilesList[];
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    // 创建临时预览URL
    const tempUrl = URL.createObjectURL(file);

    // 添加到文件列表，初始状态为loading
    const fileItem = {
      uid: crypto.randomUUID(),
      name: file.name,
      fileSize: file.size,
      file,
      maxWidth: '200px',
      showDelIcon: true,
      imgPreview: true,
      imgVariant: 'square' as 'square' | 'rectangle' | undefined,
      url: tempUrl,
      status: 'uploading' as 'uploading' | 'done' | 'error',
    };

    arr.push(fileItem);
  }

  // 添加到文件列表
  filesStore.setFilesList([...filesStore.filesList, ...arr]);

  // 上传文件
  for (let i = 0; i < arr.length; i++) {
    const fileItem = arr[i];
    try {
      const formData = new FormData();
      formData.append('file', fileItem.file);

      const response = await uploadFile(formData);

      // 根据响应结果更新状态
      if (response.code === 200) {
        // 更新文件状态为成功
        const index = filesStore.filesList.findIndex(item => item.uid === fileItem.uid);
        if (index !== -1) {
          // 保持使用本地预览URL，不替换为服务器返回的URL
          // 根据返回数据获取文件ID
          if (response.data && Array.isArray(response.data) && response.data.length > 0) {
            // 处理返回数组的情况: {"code":200,"message":"上传成功","data":[{"id":3,"url":"http://xxxx"}]}
            filesStore.filesList[index].fileId = response.data[0].id;
          }
          else if (response.data && typeof response.data === 'object' && 'id' in response.data) {
            // 处理返回单个对象的情况: {"code":200,"message":"上传成功","data":{"id":3,"url":"http://xxxx"}}
            filesStore.filesList[index].fileId = (response.data as { id: number }).id;
          }
          filesStore.filesList[index].status = 'done';
        }
      }
      else {
        // 更新文件状态为错误
        const index = filesStore.filesList.findIndex(item => item.uid === fileItem.uid);
        if (index !== -1) {
          filesStore.filesList[index].status = 'error';
        }
        ElMessage.error(response.message || '上传失败');
      }
    }
    catch (error) {
      // 更新文件状态为错误
      const index = filesStore.filesList.findIndex(item => item.uid === fileItem.uid);
      if (index !== -1) {
        filesStore.filesList[index].status = 'error';
      }
      ElMessage.error('上传失败');
    }
  }
}

function handleUploadImages() {
  // 检查当前已有的图片数量
  const currentImageCount = filesStore.filesList.filter(file => file.file.type.startsWith('image/')).length;

  // 如果已经达到了图片上限，则不允许继续上传
  if (currentImageCount >= 3) {
    ElMessage.warning(`最多只能上传3张图片，当前已达到上限`);
    return;
  }

  openImage();
}

function handleUploadFiles() {
  // 检查是否已经有非图片文件
  const hasNonImageFile = filesStore.filesList.some(file => !file.file.type.startsWith('image/'));
  if (hasNonImageFile) {
    ElMessage.warning('只能上传一份文件');
    return;
  }

  openFiles();
}

// 计算属性：是否显示图片上传按钮
const showImageUpload = computed(() => {
  return modelStore.currentModelInfo?.image_enabled === true;
});

// 计算属性：是否显示文件上传按钮
const showFileUpload = computed(() => {
  return modelStore.currentModelInfo?.doc_enabled === true;
});

// 监听模型变化，如果模型不支持某种类型，清除已上传的对应文件
watch(
  () => modelStore.currentModelInfo,
  (newModelInfo) => {
    // 如果模型不支持图片，清除已上传的图片
    if (newModelInfo?.image_enabled !== true) {
      // 过滤掉图片文件，只保留非图片文件
      const nonImageFiles = filesStore.filesList.filter(file => !file.file.type.startsWith('image/'));
      filesStore.setFilesList(nonImageFiles);
    }

    // 如果模型不支持文件，清除已上传的文件
    if (newModelInfo?.doc_enabled !== true) {
      // 过滤掉非图片文件，只保留图片文件
      const imageFiles = filesStore.filesList.filter(file => file.file.type.startsWith('image/'));
      filesStore.setFilesList(imageFiles);
    }
  },
  { deep: true },
);
</script>

<template>
  <div class="files-select flex gap-4px">
    <div
      v-if="showImageUpload"
      class="flex items-center gap-4px p-6px rounded-6px cursor-pointer font-size-14px border-1px border-[rgba(0,0,0,0.08)] border-solid hover:bg-[rgba(0,0,0,.04)]"
      @click="handleUploadImages"
    >
      <el-icon>
        <Picture />
      </el-icon>
    </div>

    <div
      v-if="showFileUpload"
      class="flex items-center gap-4px p-6px rounded-6px cursor-pointer font-size-14px border-1px border-[rgba(0,0,0,0.08)] border-solid hover:bg-[rgba(0,0,0,.04)]"
      @click="handleUploadFiles"
    >
      <el-icon>
        <Document />
      </el-icon>
    </div>
  </div>
</template>

<style scoped lang="scss"></style>
